<template>
  <div class="vue-amazing-selector" :style="`height: ${height}px;`">
    <i class="el-icon-search" id="first"></i>

    <input
      placeholder="站名/站码/拼音"
      type="text"
      :class="['m-select-wrap', { 'hover focus': !disabled, disabled: disabled }]"
      :style="`width: ${width - 2}px; height: ${height - 2}px;`"
      tabindex="0"
      @blur="onBlur"
      @click="disabled ? (e) => e.preventDefault() : openSelect()"
      @input="input"
      :value="valueInput"
    />

    <i
      class="el-icon-circle-close"
      id="last"
      v-show="valueInput ? true : false"
      @click.prevent="clearValue"
    ></i>

    <transition name="fade">
      <div
        v-show="showOptions"
        class="m-options-panel"
        :style="`top: ${height + 6}px; line-height: ${height - 12}px; max-height: ${
          num * (height - 2)
        }px; width: ${width}px;`"
      >
        <p
          :class="[
            'u-option',
            {
              'option-selected': item[label] === selectedName,
              'option-hover': !item.disabled && item[value] === hoverValue,
              'option-disabled': item.disabled,
            },
          ]"
          :title="item[label]"
          @mouseenter="onEnter(item[value])"
          @click="
            item.disabled
              ? (e) => e.preventDefault()
              : onChange(item, item[label], item[value], index)
          "
          v-for="(item, index) in selectList"
          :key="index"
        >
          {{ item[label] }}
        </p>
      </div>
    </transition>
  </div>
</template>
<script>
import pinMatch from 'pinyin-match';
import _ from 'lodash';
export default {
  name: 'VueAmazingSelector',
  model: {
    prop: 'valueInput',
    event: 'input',
  },
  props: {
    selectData: {
      // 下拉框字典数据
      type: Array,
      default: () => {
        return [];
      },
    },
    valueInput: {
      // 下拉初始默认值
      type: [Number, String],
      default: null,
    },
    label: {
      // 下拉字典项的文本
      type: String,
      default: 'label',
    },
    value: {
      // 下拉字典项的值
      type: String,
      default: 'value',
    },
    // 是否开启过滤
    filterable: {
      type: Boolean,
      default: false,
    },
    placeholder: {
      // 下拉框默认文字
      type: String,
      default: '请选择',
    },
    disabled: {
      // 是否禁用下拉
      type: Boolean,
      default: false,
    },
    width: {
      // 下拉框宽度
      type: Number,
      default: 180,
    },
    height: {
      // 下拉框高度
      type: Number,
      default: 29,
    },
    num: {
      // 下拉面板最多能展示的下拉项数，超过后滚动显示
      type: Number,
      default: 6,
    },
  },
  data() {
    return {
      isClear: false,
      selectList: [], //下拉框数据
      selectedName: null,
      hoverValue: null, // 鼠标悬浮项的value值
      showOptions: false,
    };
  },
  watch: {},
  computed: {},
  mounted() {
    const dedata = this.valueInput;
    this.selectData.forEach((item) => {
      if (dedata == item[this.value]) {
        this.$emit('input', item[this.label]);
        this.selectedName = item[this.label];
        this.hoverValue = item[this.value];
      }
    });

    if (this.selectData.length > 100) {
      this.selectList = _.cloneDeep(this.selectData).slice(0, 100);
    } else {
      this.selectList = _.cloneDeep(this.selectData);
    }
  },
  methods: {
    input(val) {
      this.$emit('input', val.target.value);
      if (this.filterable == true) {
        this.pinyingMatch(val.target.value, this);
      }
    },
    onBlur() {
      if (this.showOptions) {
        this.showOptions = false;
      }
    },
    onEnter(value) {
      this.hoverValue = value;
    },

    openSelect() {
      this.showOptions = true;
      this.selectList = _.cloneDeep(this.selectData).slice(0, 100);
    },

    onChange(obj, label, value, index) {
      // 选中下拉项后的回调
      this.$emit('input', label);
      this.selectedName = label;
      this.hoverValue = value;
      this.showOptions = false;
      this.$emit('change', obj, label, value, index);
    },

    pinyingMatch: _.debounce((val, that) => {
      // 有值时才执行过滤
      if (val) {
        let numRe = new RegExp(/^[0-9]*$/);

        if (numRe.test(val)) {
          that.selectList = that.selectData.filter((item) => {
            return item[that.label].indexOf(val) != -1;
          });
        } else {
          that.selectList = that.selectData.filter((item) => {
            return pinMatch.match(item[that.label], val); //(需要过滤的名称，输入的关键词)
          });
        }
      } else {
        that.selectList = _.cloneDeep(that.selectData).slice(0, 100);
      }
    }, 200),

    clearValue() {
      this.$emit('input', '');
    },
  },
};
</script>

<style lang="less" scoped>
@themeColor: #1890ff; // 自定义主题色

input:focus {
  outline: none;
}

input,
p {
  margin: 0;
  padding: 0;
}

.vue-amazing-selector {
  z-index: 999;
  position: relative;
  display: inline-block;
  font-size: 14px;
  font-weight: 400;
  color: rgba(0, 0, 0, 0.65);

  #first {
    line-height: 27px;
    z-index: 99;
    position: absolute;
    left: 5px;
  }

  #last {
    line-height: 27px;
    z-index: 99;
    position: absolute;
    right: 5px;
    cursor: pointer;
  }
}

// 渐变过渡效果
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s;
}

.fade-enter,
.fade-leave-to {
  opacity: 0;
}

.m-select-wrap {
  position: relative;
  display: inline-block;
  border: 1px solid #d9d9d9;
  line-height: 27px;
  border-radius: 4px;
  cursor: pointer;
  padding: 0px 30px 0px 20px;
  box-sizing: border-box;
  transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);

  .u-select-input {
    display: block;
    text-align: left;
    margin-left: 11px;
    margin-right: 24px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .placeholder {
    color: #bfbfbf;
  }

  .triangle {
    position: absolute;
    top: 50%;
    right: 12px;
    width: 12px;
    height: 12px;
    fill: rgba(0, 0, 0, 0.25);
    transform: translateY(-50%);
    -webkit-transform: translateY(-50%);
    transition: all 0.3s ease-in-out;
    pointer-events: none;
  }

  .rotate {
    transform: translateY(-50%) rotate(180deg);
    -webkit-transform: translateY(-50%) rotate(180deg);
  }
}

.hover {
  // 悬浮时样式
  &:hover {
    border-color: @themeColor;
  }
}

.focus {
  // 激活时样式
  &:focus {
    // 需设置元素的tabindex属性
    border-color: @themeColor;
    box-shadow: 0 0 0 2px rgba(24, 144, 255, 20%);
  }
}

.disabled {
  // 下拉禁用样式
  color: rgba(0, 0, 0, 0.25);
  background: #f5f5f5;
  user-select: none;
  cursor: not-allowed;
}

.m-options-panel {
  position: absolute;
  z-index: 999;
  overflow: auto;
  background: #fff;
  padding: 4px 0;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 15%);

  .u-option {
    // 下拉项默认样式
    text-align: left;
    position: relative;
    display: block;
    padding: 5px 12px;
    font-weight: 400;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    cursor: pointer;
    transition: background 0.3s ease;
  }

  .option-selected {
    // 被选中的下拉项样式
    font-weight: 600;
    background: #fafafa;
  }

  .option-hover {
    // 悬浮时的下拉项样式
    background: #e6f7ff;
  }

  .option-disabled {
    // 禁用某个下拉选项时的样式
    color: rgba(0, 0, 0, 0.25);
    user-select: none;
    cursor: not-allowed;
  }
}
</style>
